package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.system.domain.*;
import org.footballmanager.pandafootball.system.domain.enums.BFLX;
import org.footballmanager.pandafootball.system.domain.enums.BFZT;
import org.footballmanager.pandafootball.system.form.impl.FootCupbfSearchForm;
import org.footballmanager.pandafootball.system.mapper.FootCupbfMapper;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class FootCupbfServiceImpl extends ServiceImpl<FootCupbf> implements FootCupbfService {
	public static final double TOP16WIN = 15D;
	public static final double TOP16LOSE = 10D;
	
	public static final double TOP32WIN = 10D;
	public static final double TOP32LOSE = 8D;
	
    @Autowired
    private FootCupbfMapper footCupbfMapper;
	@Autowired
	private FootSjService footSjService;
	@Autowired
	private FootChipService footChipService;
	@Autowired
	private FootUserService footUserService;
	@Autowired
	private FootTeamService footTeamService;
	@Autowired
	private FootUserPersonService footUserPersonService;
	@Autowired
	private FootZjService footZjService;
	@Autowired
	private FootZnxService footZnxService;
	@Autowired
	private FootCupbmService footCupbmService;

	@Override
	public int delete(Serializable id, HttpServletRequest request) {
		FootCupbf t = this.get(id);
		log.info("删除杯赛报分:" + t.toString());
		if(t.getBfzt().equals(BFZT.HAVE)){
			this.ffjj(t, false, request);
		}
		t.setBfzt(BFZT.NOT);
		t.setJq1(0);
		t.setJq2(0);
		return super.delete(id, request);
	}

	@Override
	public int save(FootCupbf t, HttpServletRequest request) {
		footZnxService.sendZnx(t.getQd1(), t.getQd2(), "请确认" + t.getBflx().name() + "比赛结果",
				null, "/hy/footCupbf/view", request);
		return super.save(t, request);
	}

	/**
	 * 确认报分信息
	 */
	@Override
	@Transactional
	public void makesure(FootCupbf bf, HttpServletRequest request) {
		footUserPersonService.autoDeletePerson(bf.getQd1(), request);
		footUserPersonService.autoDeletePerson(bf.getQd2(), request);
        bf.setBfzt(BFZT.HAVE);
        this.updateNotNull(bf, request);
        FootCupbm fc1 = footCupbmService.findCupbmByUserid(bf.getQd1());
        FootCupbm fc2 = footCupbmService.findCupbmByUserid(bf.getQd2());
        if(bf.getTime1()){
            if(bf.getJq1() > bf.getJq2()){
                fc1.setJj1(true);
            }else{
                fc2.setJj1(true);
            }
        }else if(bf.getTime2()){
            if(bf.getJq1() > bf.getJq2()){
                fc1.setJj2(true);
            }else{
                fc2.setJj2(true);
            }
        }else if(bf.getTime3()){
            if(bf.getJq1() > bf.getJq2()){
                fc1.setJj3(true);
            }else{
                fc2.setJj3(true);
            }
        }else if(bf.getTime4()){
            if(bf.getJq1() > bf.getJq2()){
                fc1.setJj4(true);
            }else{
                fc2.setJj4(true);
            }
        }
        footCupbmService.updateNotNull(fc1, request);
        footCupbmService.updateNotNull(fc2, request);
        //发放奖金
        this.ffjj(bf, true, request);
	}

	private void ffjj(FootCupbf bf, boolean isadd, HttpServletRequest request) {
		if(bf.getBflx().equals(BFLX.WINNER)){
			//冠军杯站内信和财政变动
            processChangeMoney(bf, isadd, request, TOP16WIN, TOP16LOSE);
		}else{
			//联盟杯站内信和财政变动
            processChangeMoney(bf, isadd, request, TOP32WIN, TOP32LOSE);
		}
	}

	private void processChangeMoney(FootCupbf bf, boolean isadd, HttpServletRequest request, Double win, Double lose){
        FootTeam team1 = footTeamService.getTeamByUserid(bf.getQd1());
        FootTeam team2 = footTeamService.getTeamByUserid(bf.getQd2());
        if(bf.getJq1() > bf.getJq2()){
            this.changeMoney(team1, win, bf.getBflx(), isadd, request);
            this.changeMoney(team2, lose, bf.getBflx(), isadd, request);
        }else{
            this.changeMoney(team1, lose, bf.getBflx(), isadd, request);
            this.changeMoney(team2, win, bf.getBflx(), isadd, request);
        }
    }

	private void changeMoney(FootTeam team1, double money, BFLX bflx, boolean isadd, HttpServletRequest request) {
		String result = "已" + (isadd ? "确认" : "删除") + "比分,获得" + bflx.name() + "比赛奖金€" +
				new DecimalFormat(",###").format(money) + ",当前总资金为:€" +
                new DecimalFormat(",###").format(team1.getQdZzj());
		if(isadd){
			team1.setQdZzj(team1.getQdZzj() + money);
		}else{
			team1.setQdZzj(team1.getQdZzj() - money);
		}
		footZnxService.sendZnx(footUserService.getAdminUserid(), team1.getUserId(), result, null, null, request);
		footZjService.sendZj(team1.getUserId(), money, isadd, result, request);
		footTeamService.updateNotNull(team1, request);
	}

    @Override
	public void createBf(int times, boolean type, HttpServletRequest request) {
		List<Long> tl = new ArrayList<>();
		List<FootCupbm> bmlist = footCupbmService.findByTypeAndSj(type, footSjService.getSj());
        if(bmlist == null || bmlist.isEmpty()) {
            return;
        }
		if(times == 1){
        	processTimes1(bmlist, tl, times, type, request);
		}else if(times == 2){
			processTimes2(bmlist, tl, times, type, request);
		}else if(times == 3){
			processTimes3(bmlist, tl, times, type, request);
		}else if(times == 4){
			processTimes4(bmlist, tl, times, type, request);
		}else{
			processTimes5(type, request);
		}
	}

	private void processTimes5(boolean type, HttpServletRequest request) {
		//确认第四次报分结果
		this.makesureLastTime("time4", request);
		this.reward(type, request);
	}

	private void processTimes4(List<FootCupbm> bmlist, List<Long> tl, int times, boolean type, HttpServletRequest request) {
		//确认第三次报分结果
		this.makesureLastTime("time3", request);
		for(int i = 0; i < bmlist.size(); i = i + 8){
			boolean isAdd = false;
			for(int j = 0; j < 8; j++){
				FootCupbm fc = bmlist.get(i + j);
				if(fc.getJj3()){
					tl.add(fc.getUserId());
					isAdd = true;
				}
			}
			if(!isAdd){
				tl.add(0L);
			}
		}
		this.addCupBf2Table(times, tl, type, request);
	}

	private void processTimes3(List<FootCupbm> bmlist, List<Long> tl, int times, boolean type, HttpServletRequest request) {
		//确认第二次报分结果
		this.makesureLastTime("time2", request);
		for(int i = 0; i < bmlist.size(); i = i + 4){
			boolean isAdd = false;
			for(int j = 0; j < 4; j++){
				FootCupbm fc = bmlist.get(i + j);
				if(fc.getJj2()){
					tl.add(fc.getUserId());
					isAdd = true;
				}
			}
			if(!isAdd){
				tl.add(0L);
			}
		}
		this.addCupBf2Table(times, tl, type, request);
	}

	private void processTimes2(List<FootCupbm> bmlist, List<Long> tl, int times, boolean type, HttpServletRequest request) {
		//确认第一次报分结果
		this.makesureLastTime("time1", request);
		for(int i = 0; i < bmlist.size(); i = i + 2){
			boolean isAdd = false;
			for(int j = 0; j < 2; j++){
				FootCupbm fc = bmlist.get(i + j);
				if(fc.getJj1()){
					tl.add(fc.getUserId());
					isAdd = true;
				}
			}
			if(!isAdd){
				tl.add(0L);
			}
		}
		this.addCupBf2Table(times, tl, type, request);
	}

	private void processTimes1(List<FootCupbm> bmlist, List<Long> tl, int times, boolean type, HttpServletRequest request) {
		for(FootCupbm fc: bmlist){
			if(null != fc.getUserId()){
				tl.add(fc.getUserId());
			}else{
				tl.add(0L);
			}
		}
		this.addCupBf2Table(times, tl, type, request);
	}

	private void reward(boolean type, HttpServletRequest request) {
		FootCupbm bm = footCupbmService.getTop1(type);
		if(bm != null){
			this.rewardTop1(bm, type, request);
		}
	}

	private void rewardTop1(FootCupbm bm, boolean type, HttpServletRequest request) {
		FootTeam team = footTeamService.getTeamByUserid(bm.getUserId());
		if(team != null){
			double money = type ? 100D : 50D;
			team.setQdZzj(team.getQdZzj() + money);
			//获取碎片
			int numOfChip = type ? 5 : 3;
			String purpleNumber = String.valueOf(numOfChip);
			footChipService.randomGetChip(team.getUserId(), 4, numOfChip, request);
			numOfChip = type ? 2 : 1;
			String orangeNumber = String.valueOf(numOfChip);
			footChipService.randomGetChip(team.getUserId(), 5, numOfChip, request);

			String title = type ? "冠军杯" : "联盟杯";
			String result = "恭喜您,获得" + title + "冠军,发放奖金€" + new DecimalFormat(",###").format(money) + "及紫色碎片" + purpleNumber +
				"个和橙色碎片" + orangeNumber + "个,当前总资金为:€" + new DecimalFormat(",###").format(team.getQdZzj());
			footZnxService.sendZnx(footUserService.getAdminUserid(), team.getUserId(), result, null, null, request);
			footZjService.sendZj(team.getUserId(), money, true, result, request);
			footTeamService.updateNotNull(team, request);
		}
	}

    /**
     * 如果上次报分没有结束，强制结束上次报分
     * @param times 次数
     * @param request 请求
     */
	private void makesureLastTime(String times, HttpServletRequest request) {
        Example example = new Example(FootCupbf.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
	    criteria.andEqualTo(times, true);
        criteria.andEqualTo("bfzt", BFZT.NOT);
		List<FootCupbf> list = this.findall(example);
		if(list != null && !list.isEmpty()){
			for(FootCupbf fc: list){
				fc.setBfzt(BFZT.HAVE);
				this.updateNotNull(fc, request);
			}
		}
	}

    /**
     * 根据次数和用户主键列表，添加新的报分记录到数据库
     * @param times 次数
     * @param userIds 用户列表
     * @param type 类型
     * @param request 请求
     */
	private void addCupBf2Table(int times, List<Long> userIds, boolean type, HttpServletRequest request) {
		for(int i = 0; i < userIds.size(); i = i + 2){
			FootCupbf bf = new FootCupbf();
			setQdInfo(bf, userIds, i);
			//立即晋级
			this.atOnceIn(bf, times, request);
			setTime(times, bf);
			if((bf.getQd1() == null && bf.getQd2() != null) || (bf.getQd1() != null && bf.getQd2() == null)){
				bf.setBfzt(BFZT.HAVE);
			}else{
				bf.setBfzt(BFZT.NOT);
			}
			bf.setSj(footSjService.getSj());
			if(type){
				bf.setBflx(BFLX.WINNER);
			}else{
				bf.setBflx(BFLX.ALLIANCE);
			}
			this.save(bf, request);
		}
	}

	private void setQdInfo(FootCupbf bf, List<Long> userIds, int i){
		bf.setQd1(userIds.get(i));
		FootUser zhuuser = footUserService.get(userIds.get(i));
		if(zhuuser != null){
			bf.setQd1Name(zhuuser.getNike());
		}else{
			bf.setQd1Name("");
		}
		if((i + 1) < userIds.size()){
			bf.setQd2(userIds.get(i + 1));
			FootUser keuser = footUserService.get(userIds.get(i + 1));
			if(keuser != null){
				bf.setQd2Name(keuser.getNike());
			}else{
				bf.setQd2Name("");
			}
		}else{
			bf.setQd2(null);
			bf.setQd2Name("");
		}
	}

	private void setTime(int times, FootCupbf bf){
		if(times == 1){
			bf.setTime1(true);
		}else if(times == 2){
			bf.setTime2(true);
		}else if(times == 3){
			bf.setTime3(true);
		}else if(times == 4){
			bf.setTime4(true);
		}
	}

    /**
     * 立即晋级
     * @param bf 报分实体类
     * @param times 次数
     * @param request 请求
     */
    @Override
	public void atOnceIn(FootCupbf bf, int times, HttpServletRequest request) {
        Example example = new Example(FootCupbm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
		if(bf.getQd1() == null && bf.getQd2() != null){
		    criteria.andEqualTo(Constants.USERID, bf.getQd2());
		}else if(bf.getQd1() != null && bf.getQd2() == null){
		    criteria.andEqualTo(Constants.USERID, bf.getQd1());
		}else{
			return;
		}
		FootCupbm fc = footCupbmService.findByExample(example);
		if(times == 1){
			fc.setJj1(true);
		}else if(times == 2){
			fc.setJj2(true);
		}else if(times == 3){
			fc.setJj3(true);
		}else if(times == 4){
			fc.setJj4(true);
		}
		footUserPersonService.autoDeletePerson(bf.getQd1(), request);
		footUserPersonService.autoDeletePerson(bf.getQd2(), request);
		footCupbmService.updateNotNull(fc, request);
	}
	
	/**
	 * 立即晋级
	 * @param bf 报分实体类
     * @param request 请求
	 */
    @Override
	public void atOnceIn(FootCupbf bf, HttpServletRequest request) {
		List<FootPerson> zhulist = footUserPersonService.findFootPersonByUserId(bf.getQd1(), request);
		List<FootPerson> kelist = footUserPersonService.findFootPersonByUserId(bf.getQd2(), request);
        Example example = new Example(FootCupbm.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
		if(zhulist.size() < 18 && kelist.size() >= 18){
		    criteria.andEqualTo(Constants.USERID, bf.getQd2());
		}else if(zhulist.size() >= 18 && kelist.size() < 18){
            criteria.andEqualTo(Constants.USERID, bf.getQd1());
		}else{
			return;
		}
		FootCupbm fc = footCupbmService.findByExample(example);
		fc.setJj1(bf.getTime1());
		fc.setJj2(bf.getTime2());
		fc.setJj3(bf.getTime3());
		fc.setJj4(bf.getTime4());
		footUserPersonService.autoDeletePerson(bf.getQd1(), request);
		footUserPersonService.autoDeletePerson(bf.getQd2(), request);
		footCupbmService.updateNotNull(fc, request);
	}

    @Override
	public List<FootCupbf> findBf(String times, Long sj, boolean type) {
        Example example = new Example(FootCupbf.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", sj);
        BFLX lx = type ? BFLX.WINNER : BFLX.ALLIANCE;
	    criteria.andEqualTo("bflx", lx);
	    criteria.andEqualTo(times, true);
	    example.orderBy("id asc");
		return this.findall(example);
	}

    @Override
	public FootCupbf findFirstBfResult(Long userId) {
        Example example = new Example(FootCupbf.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
	    criteria.andEqualTo("bfzt", BFZT.HAVE);
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("qd1", userId);
        criteria2.andEqualTo("qd2", userId);
        example.or(criteria2);
		return this.findByExample(example);
	}

    @Override
	public FootCupbf findCupbfByUserid(Long userId) {
        Example example = new Example(FootCupbf.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("bfzt", BFZT.NOT);
        criteria.andIsNull("bfUserId");
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("qd1", userId);
        criteria2.andEqualTo("qd2", userId);
        example.or(criteria2);
        return this.findByExample(example);
	}

	@Override
	public FootCupbf findMakesureBfByUserid(Long userId) {
        Example example = new Example(FootCupbf.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sj", footSjService.getSj());
        criteria.andEqualTo("bfzt", BFZT.NOT);
        criteria.andNotEqualTo("bfUserId", userId);
        Example.Criteria criteria2 = example.createCriteria();
        criteria.andEqualTo("qd1", userId);
        criteria2.andEqualTo("qd2", userId);
        example.or(criteria2);
        return this.findByExample(example);
	}

    /**
     * 翻页方法
     *
     * @param footCupbfSearchForm 条件
     * @return 列表
     */
    @Override
    public List<FootCupbf> findall(FootCupbfSearchForm footCupbfSearchForm) {
        return footCupbfMapper.findall(footCupbfSearchForm);
    }

	/**
	 * 根据主键获取记录
	 * @param id 主键
	 * @return 记录
	 */
	@Override
	public FootCupbf get(Serializable id) {
		return footCupbfMapper.findById(id);
	}

    /**
     * 查询
     *
     * @param entityname          实体类名
     * @param map                 参数
     * @param footCupbfSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootCupbfSearchForm footCupbfSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footCupbfSearchForm);
        Page<FootCupbf> page = PageHelper.startPage(footCupbfSearchForm.getPageIndex(), footCupbfSearchForm.getPageSize());
        List<FootCupbf> list = this.findall(footCupbfSearchForm);
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
        map.addAttribute("title", footCupbfSearchForm.getBflx().name());
    }

    /**
     * 删除所有
     *
     * @param footCupbfSearchForm 条件
     * @param request             请求
     */
    @Override
    public void deleteAll(FootCupbfSearchForm footCupbfSearchForm, HttpServletRequest request) {
        if(footCupbfSearchForm.getSelectIds() != null){
            String[] result = footCupbfSearchForm.getSelectIds().split(Constants.COMMA);
            for(String id: result){
                this.delete(Long.parseLong(id), request);
            }
        }
    }
}
